import { Component, ContentChildren, Input, Optional, QueryList, SkipSelf } from '@angular/core'
import { FormControlName, Validators } from '@angular/forms'
import { AdFormConfig } from './form.config'
import { AdFormErrorImpl } from './form.error.class'
import { AdFormProvider } from './form.provider'

@Component({
  selector: 'ad-form-item',
  template: `<div
    class="ad-form-item-wrapper"
    [class.ad-direction-row]="getConfig('direction') !== 'column'"
    [class.ad-direction-column]="getConfig('direction') === 'column'"
    [style.align-items]="getConfig('itemAlignment') === 'center' ? 'center' : 'flex-start'"
  >
    <div
      class="ad-form-item-label"
      *ngIf="getConfig('showLabel')"
      [class.ad-start]="parentConfig('labelTextAlign') !== 'end'"
      [class.ad-end]="parentConfig('labelTextAlign') === 'end'"
      [style.marginRight.px]="getConfig('labelSpaceX')"
      [style.width]="getConfig('direction') === 'column' ? '100%' : getConfig('labelWidth') + 'px'"
    >
      <span class="ad-label-box" [class.ad-required]="isRequired"
        ><ng-container *ngIf="getConfig('labelWidth') > 0"
          >{{ label }}{{ label ? getConfig('labelSuffix') : '' }}
        </ng-container>
      </span>
    </div>
    <div class="ad-form-content" *ngIf="getConfig('showValue'); else formInput">
      <ad-form-value
        [isWrap]="getConfig('valueIsWrap')"
        [value]="value === '' ? getFormValue : value"
      ></ad-form-value>
    </div>
    <ng-template #formInput>
      <div class="ad-form-content">
        <ng-content></ng-content>
        <mat-error *ngIf="getErrorFlag"> {{ label }}{{ getErrorMessage }} </mat-error>
      </div>
    </ng-template>
  </div> `,
  providers: [],
  host: {
    '[style.width]': 'getWidth',
    '[style.paddingLeft.px]': "getConfig('spaceX')",
    '[style.marginBottom.px]': "getConfig('spaceY')",
    '[class.ad-form-item]': 'true',
  },
})
export class AdFormItemComponent implements AdFormConfig {
  private adFormErrorImpl = new AdFormErrorImpl()
  /**
   * 占用份数
   */
  @Input() row?: number = 12
  /**
   * 左边距
   */
  @Input() spaceX?: number
  /**
   * labelName
   */
  @Input() label?: string = ''
  /**
   * label宽度
   */
  @Input() labelWidth?: number
  /**
   * label右外边距
   */
  @Input() labelSpaceX?: number
  /**
   * 是否展示label label不展示则表单占满行
   */
  @Input() showLabel?: boolean
  /**
   * showValue开启后展示的value值
   */
  @Input() value?: string | number = ''
  /**
   * value 是否显示省略号
   */
  @Input() valueIsWrap?: boolean
  /**
   * 是否展示value 开启后不显示content内容
   */
  @Input() showValue?: boolean
  /**
   * 表单下边距
   */
  @Input() spaceY?: number
  /**
   * label value 对其方式  顶对齐 居中对齐
   */
  @Input() itemAlignment?: 'start' | 'center'
  /**
   * 是否必填 label前星号显示隐藏
   */
  @Input() required?: boolean
  /**
   * error展示条件
   */
  @Input() errorFlag?: boolean = undefined
  /**
   * error 内容
   */
  @Input() errorMsg?: string | string[] = undefined
  /**
   * key  value 排列方式 行对齐  列对齐
   */
  @Input() direction?: 'row' | 'column'
  /**
   * label 后方拼接字符串
   */
  @Input() labelSuffix?: string

  /**
   * 获取FormControlName指令
   */
  @ContentChildren(FormControlName, { descendants: true })
  listOfFormControlName!: QueryList<FormControlName>
  constructor(@SkipSelf() @Optional() private _AdFormProvider?: AdFormProvider) {}

  getConfig<T extends keyof AdFormConfig>(key: T): AdFormConfig[T] {
    return (this as any)[key] === undefined ? this.parentConfig(key) : (this as any)[key]
  }

  /**
   * 获取默认配置
   * @param key
   * @returns
   */
  parentConfig<T extends keyof AdFormConfig>(key: T): AdFormConfig[T] {
    return this._AdFormProvider.configure[key]
  }

  /**
   * 获取表单宽度
   */
  get getWidth() {
    return (this.row / this.parentConfig('row')) * 100 + '%'
  }

  /**
   * 获取是否为必填项
   */
  get isRequired() {
    let require = this.required || (this.required === undefined && this.parentConfig('required'))
    const control = this._AdFormProvider?.formGroup?.controls?.[this.getFormField]
    if (require === undefined && control) {
      const _rawValidators: any = (control as any)._rawValidators
      if (Array.isArray(_rawValidators)) {
        require = _rawValidators.includes(Validators.required)
      } else {
        require = [_rawValidators].includes(Validators.required)
      }
    }
    return !!require
  }

  /**
   * 获取内部表单字段
   */
  get getFormField() {
    return this.listOfFormControlName?.first?.name || ''
  }

  /**
   * 获取表单是否有错误
   */
  get getErrorFlag() {
    if (this.errorFlag !== undefined) {
      return !!this.errorFlag
    }
    const control = this._AdFormProvider?.formGroup?.controls?.[this.getFormField]
    if (!control) {
      return false
    }
    return control.invalid && control.touched
  }

  /**
   * 获取表单值
   */
  get getFormValue() {
    return this._AdFormProvider?.formGroup?.controls?.[this.getFormField]?.value
  }

  /**
   * 获取表单错误语句
   */
  get getErrorMessage() {
    let message = ''
    if (typeof this.errorMsg === 'string') {
      message = this.errorMsg
    } else if (Array.isArray(this.errorMsg)) {
      message = this.errorMsg.map((item) => item).join('')
    }
    if (message) {
      return message
    }
    const control = this._AdFormProvider?.formGroup?.controls?.[this.getFormField]
    if (control) {
      return this.adFormErrorImpl.handle(control) || ''
    }
    return message
  }
}
